import 'package:lib_util/utils/utils.dart';
import 'package:objectbox/objectbox.dart';
import '../../../sp.dart';
import '../basemodel.dart';
import 'package:crypto/crypto.dart';
import '../../../objectbox.g.dart';
import 'dart:convert';

@Entity()
class Wallet {
  @Id()
  int id;
  int type; //0-助记词 1-私钥 2-观察钱包 3-分片私钥
  String key; //助记词或者私钥, fenpian1,fenpian2,fenpian3
  String? name;
  String? salt; // 类型等于 3 的是否 有 这个 salt
  String uId; // 用户id
  String? appleFileId; // 是否已经上传苹果云，拿到上传的文件名
  String? googleFileId; // 是否已经上传谷歌云，拿到上传文件id
  bool isServerBackUp; //是否已经上传服务器
  bool? backup; // 是否备份

  Wallet(
      {this.id = 0,
      required this.key,
      required this.type,
      required this.uId,
      this.salt = '',
      this.name,
      this.appleFileId,
      this.googleFileId,
      this.isServerBackUp = false,
      this.backup});

  bool isHDWallet() {
    return type == 0;
  }

  bool isWatchWallet() {
    return type == 2;
  }

  bool needBackup() {
    return isHDWallet() && (null == backup || !backup!);
  }

  @override
  String toString() {
    return '{id: $id, type: $type, key: $key, name: $name, uId: $uId, salt: $salt,backup: $backup,appleFileId: $appleFileId,googleFileId: $googleFileId}';
  }

  String getName() {
    if (Utils.isEmpty(name)) {
      return '${'Wallet '}$id';
    }
    return name!;
  }

  String getMd5Key() {
    return md5.convert(key.codeUnits).toString();
  }
}

class WalletModel extends BaseModel<Wallet> {
  WalletModel(Box<Wallet> box) : super(box);

  String saveWalletListSequence(List<Wallet> list) {
    String data = list.map((e) => e.id).toList(growable: false).join(',');
    SP().setWalletSortIdList(data);
    return data;
  }

  List<Wallet> getSortedWalletList() {
    List<Wallet> list = box.getAll();
    String sortData = SP().getWalletSortIdList();
    if (Utils.isEmpty(sortData)) {
      sortData = saveWalletListSequence(list);
    }
    List<int> sequence =
        sortData.split(',').map((e) => int.parse(e)).toList(growable: false);
    // Config.logger.d(sortData);
    list.sort((a, b) {
      int aIndex = sequence.indexOf(a.id);
      int bIndex = sequence.indexOf(b.id);
      if (aIndex != -1 && bIndex != -1) {
        return aIndex - bIndex;
      } else if (aIndex != bIndex) {
        //有1个在排序里，1个不在
        return aIndex > bIndex ? -1 : 1;
      } else {
        //2个都不在排序里，按照id进行排序
        return a.id - b.id;
      }
    });
    return list;
  }

  Wallet? getWalletById(int id) {
    return box.query(Wallet_.id.equals(id)).build().findFirst();
  }

  // 通过 用户id 查询
  Wallet? getWalletByUId(String uId) {
    return box.query(Wallet_.uId.equals(uId)).build().findFirst();
  }

  // 通过 用户id 查询 除外
  Wallet? getWalletByUIdExcept(String uId) {
    return box.query(Wallet_.uId.notEquals(uId)).build().findFirst();
  }

  Wallet? getWalletByIdExcept(int id) {
    return box.query(Wallet_.id.notEquals(id)).build().findFirst();
  }

  List<Wallet> getWalletList() {
    return box.getAll();
  }

  bool hasWallet() {
    return getWalletList().isNotEmpty;
  }

  updateWalletName(int id, String name) {
    Wallet? wallet = getWalletById(id);
    if (null != wallet) {
      wallet.name = name;
      box.put(wallet, mode: PutMode.update);
    }
  }

  updateWalletBackupState(int id) {
    Wallet? wallet = getWalletById(id);
    if (null != wallet) {
      wallet.backup = true;
      box.put(wallet, mode: PutMode.update);
    }
  }

  updateWalletGoogleFileId(Wallet? wallet, String value) {
    if (null != wallet) {
      wallet.googleFileId = value;
      box.put(wallet, mode: PutMode.update);
      updateWalletKeyEmpty(wallet, 2);
    }
  }

  updateWalletAppleFileId(Wallet? wallet, String value) {
    if (null != wallet) {
      wallet.appleFileId = value;
      box.put(wallet, mode: PutMode.update);
      updateWalletKeyEmpty(wallet, 2);
    }
  }

  updateWalletType(Wallet? wallet, int type, String key) {
    if (null != wallet) {
      wallet.type = type;
      wallet.key = key;
      print('updateWalletType ::::: ${wallet.toString()}');
      box.put(wallet, mode: PutMode.update);
    }
  }

  //type: 1是本地，2是云端, 3是服务器
  updateWalletKeyEmpty(Wallet? wallet, int type) {
    if (null != wallet) {
      //这里处理key有多少，
      //通过','隔开
      var keyList = wallet.key.split(',');
      if (keyList.length == 1) {
        //如果长度是1，那就是只有本地key，那没有变化就不用保存数据库了，
        return;
      }
      if (keyList.length == 2) {
        //出现长度是2，一定是上传了服务器的情况，所以只需要处理type==2的，其他情况不处理
        switch (type) {
          case 2:
            keyList.removeLast();
            break;
          default:
            return;
        }
      }
      if (keyList.length == 3) {
        switch (type) {
          case 2:
            //当有3片，又要更新云端的时候，那就置空
            keyList[1] = '';
            break;
          case 3:
            //当有3片，又要更新服务端的时候，直接删掉
            keyList.removeLast();
            //然后还要判断第二片是否为空，是的话也要删除（因为有可能服务器没上传，但是手动上传了云端）
            if (keyList[1].isEmpty) {
              keyList.removeAt(1);
            }
            break;
          default:
        }
      }

      wallet.key = keyList.join(',');
      box.put(wallet, mode: PutMode.update);

      if (keyList.length == 1) {
        //如果最后只有1片了，那就更新说已经完全备份
        updateWalletBackupState(wallet.id);
      }
    }
  }
}
